<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!--<script src="../jquery-3.6.0.js"></script>-->
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
 
        .bg {
            width: 100%;
            height:360px;
            background-color:#333;
            margin:20px auto;
            color: #fff;
            overflow: hidden;
            position: relative;
            font-family: "微软雅黑";
        }
 
        .bg ul {
            width: 100%;
            position: absolute;
            top: 0;
            left: 0;
            list-style: none;
        }
 
        .bg ul li {
            width: 100%;
            height: 30px;
            line-height: 30px;
            text-align: center;
        }

        .bg ul li.active {
            color: #2ecc71;
            font-weight: bold;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div class="bg"></div>
    <center> <audio src="刘瑞琦 - 七里香.mp3" controls="controls"></audio></center>
<script>
    $(function() {
        function parseLyric(text) {
            //按行分割歌词
            let lyricArr = text.split('\n');
            //console.log(lyricArr)//0: "[ti:七里香]" "[ar:周杰伦]"...
            let result = []; //新建一个数组存放最后结果
            //遍历分割后的歌词数组，将格式化后的时间节点，歌词填充到result数组
            for (i = 0; i < lyricArr.length; i++) {
                let playTimeArr = lyricArr[i].match(/\[\d{2}:\d{2}((\.|\:)\d{2})\]/g); //正则匹配播放时间
                let lineLyric = "";
                if (lyricArr[i].split(playTimeArr).length > 0) {
                    lineLyric = lyricArr[i].split(playTimeArr);
                }

                if (playTimeArr != null) {
                    for (let j = 0; j < playTimeArr.length; j++) {
                        let time = playTimeArr[j].substring(1, playTimeArr[j].indexOf("]")).split(":");
                        //数组填充
                        result.push({
                            time: (parseInt(time[0]) * 60 + parseFloat(time[1])).toFixed(4),
                            content: String(lineLyric).substr(1)
                        });
                    }
                }


            }
            return result;
        }


        let text = "[ti:七里香]\n[ar:周杰伦]\n[al:七里香]\n[by:]\n[offset:0]\n[00:00.00]七里香 - 周杰伦 (Jay Chou)\n[00:02.96]词：方文山\n[00:4.93]曲：周杰伦\n[00:6.90]编曲：钟兴民\n[00:14.87]窗外的麻雀在电线杆上多嘴\n[00:21.52]你说这一句很有夏天的感觉\n[00:28.23]手中的铅笔在纸上来来回回\n[00:34.58]我用几行字形容你是我的谁\n[00:40.31]\n[00:40.31]秋刀鱼的滋味猫跟你都想了解\n[00:47.65]初恋的香味就这样被我们寻回\n[00:54.74]那温暖的阳光像刚摘的鲜艳草莓\n[01:01.21]你说你舍不得吃掉这一种感觉\n[01:07.91]雨下整夜我的爱溢出就像雨水\n[01:14.67]院子落叶跟我的思念厚厚一叠\n[01:21.41]几句是非也无法将我的热情冷却\n[01:29.41]\n[01:29.95]你出现在我诗的每一页\n[01:35.11]雨下整夜我的爱溢出就像雨水\n[01:41.64]窗台蝴蝶像诗里纷飞的美丽章节\n[01:48.42]我接着写\n[01:51.91]把永远爱你写进诗的结尾\n[01:55.98]你是我唯一想要的了解\n[02:28.80]\n[02:28.80]雨下整夜我的爱溢出就像雨水\n[02:35.68]院子落叶跟我的思念厚厚一叠\n[02:42.43]几句是非也无法将我的热情冷却\n[02:49.03]你出现在我诗的每一页\n[03:08.79]\n[02:56.46]那饱满的稻穗幸福了这个季节\n[03:03.77]而你的脸颊像田里熟透的蕃茄\n[03:09.82]你突然对我说七里香的名字很美\n[03:16.27]我此刻却只想亲吻你倔强的嘴\n[03:22.97]雨下整夜我的爱溢出就像雨水\n[03:29.72]院子落叶跟我的思念厚厚一叠\n[03:36.43]几句是非也无法将我的热情冷却\n[03:44.90]你出现在我诗的每一页\n[03:51.76]\n[03:51.50]整夜我的爱溢出就像雨水\n[03:56.58]窗台蝴蝶像诗里纷飞的美丽章节\n[04:03.66]我接着写\n[04:05.42]\n[04:05.42]把永远爱你写进诗的结尾\n[04:11.01]你是我唯一想要的了解";

        let audio = document.querySelector('audio');

        let result = parseLyric(text); //执行lyc解析


        // 把生成的数据显示到界面上去
        let $ul = $("<ul></ul>");
        for (let i = 0; i < result.length; i++) {
            let $li = $("<li></li>").text(result[i].content);
            $ul.append($li);
        }
        $(".bg").append($ul);

        let lineNo = 0; // 当前行歌词
        let preLine = 6; // 当播放6行后开始滚动歌词
        let lineHeight = -30; // 每次滚动的距离

        // 滚动播放 歌词高亮  增加类名active
        function highLight() {
            let $li = $("li");
            $li.eq(lineNo).addClass("active").siblings().removeClass("active");
            if (lineNo > preLine) {
                $ul.stop(true, true).animate({ top: (lineNo - preLine) * lineHeight });
            }
        }

        highLight();

        // 播放的时候不断渲染
        audio.addEventListener("timeupdate", function() {
            if (lineNo == result.length) return;
            if ($("li").eq(0).hasClass("active")) {
                $("ul").css("top", "0");
            }
            lineNo =getLineNo(audio.currentTime);
            highLight();
            lineNo++;
        });

        // 当快进或者倒退的时候，找到最近的后面那个result[i].time
        function getLineNo(currentTime) {
            if (currentTime >= parseFloat(result[lineNo].time)) {
                // 快进
                for (let i = result.length - 1; i >= lineNo; i--) {
                    if (currentTime >= parseFloat(result[i].time)) {
                        return i;
                    }
                }
            } else {
                // 后退
                for (let i = 0; i <= lineNo; i++) {
                    if (currentTime <= parseFloat(result[i].time)) {
                        return i - 1;
                    }
                }
            }
        }

        //播放结束自动回到开头
        audio.addEventListener("ended", function() {
            lineNo = 0;
            highLight();
            audio.play();
            $("ul").css("top", "0");
        });
    });
</script>
</html>